package com.chaosj.skill.prometheus.configurer

import com.chaosj.skill.prometheus.customizer.MeterRegistryCustomizer
import io.micrometer.core.instrument.MeterRegistry
import io.micrometer.core.instrument.Metrics
import io.micrometer.core.instrument.binder.MeterBinder
import io.micrometer.core.instrument.config.MeterFilter

/**
 * @Description:
 * @author caoyangjie
 * @date 2020年01月2020/1/23日 12:00
 * @Copyright: © 赢时胜
 */
class MeterRegistryConfigurer {
    private final Collection<MeterRegistryCustomizer> customizers

    private final Collection<MeterFilter> filters

    private final Collection<MeterBinder> binders

    MeterRegistryConfigurer(Collection<MeterBinder> binders,
                                   Collection<MeterFilter> filters,
                                   Collection<MeterRegistryCustomizer> customizers) {
        this.binders = (binders != null) ? binders : Collections.emptyList()
        this.filters = (filters != null) ? filters : Collections.emptyList()
        this.customizers = (customizers != null) ? customizers : Collections.emptyList()
    }

    void configure(MeterRegistry registry) {
        // Customizers must be applied before binders, as they may add custom
        // tags or alter timer or summary configuration.
        customize(registry)
        addFilters(registry)
        addBinders(registry)
        if ( registry != Metrics.globalRegistry) {
            Metrics.addRegistry(registry)
        }
    }

    private void customize(MeterRegistry registry) {
        customizers.forEach({customizers->customizers.customize(registry)})
    }

    private void addFilters(MeterRegistry registry) {
        this.filters.forEach({filter->registry.config().meterFilter(filter)})
    }

    private void addBinders(MeterRegistry registry) {
        this.binders.forEach({binder -> binder.bindTo(registry)})
    }
}
